#include "Tcp_Server.hpp"
#include "Translate.hpp"
#include "Daemon.hpp"
#include <memory>
#include <algorithm>

using namespace std;

#define haha 9999

pxt::Translate trans;

void Usage(string proc)
{
    cout << "Usage: \n\t" << proc << " local_port\n"
         << endl;
}

void Interact(int sockfd, string &out, const string &in)
{
    char buffer[1024];

    ssize_t n = read(sockfd, buffer, sizeof(buffer));
    if (n > 0)
    {
        buffer[n] = 0;

        write(sockfd, in.c_str(), in.size());
    }
    else if (n == 0)
    {
        lg.LogMessage(Info, "client quite ... \n");
    }
    else
    {
        lg.LogMessage(Error, "read socket err, %d : %s", errno, strerror(errno));
    }
}

void Ping(int sockfd, InetAddr addr)
{
    lg.LogMessage(Debug, "%s select %s is success, fd: %d \n", addr.PrintDebug().c_str(), "Ping", sockfd);
    string message;
    Interact(sockfd, message, "Pong");
}
void Translate(int sockfd, InetAddr addr)
{
    lg.LogMessage(Debug, "%s select %s is success, fd: %d \n", addr.PrintDebug().c_str(), "Translate", sockfd);
    char wordbuf[64];  
    ssize_t n = read(sockfd, wordbuf, sizeof(wordbuf) - 1);
    if(n > 0) wordbuf[n] = 0;

    string chinese = trans.Excute(wordbuf);
    write(sockfd, chinese.c_str(), chinese.size());

    lg.LogMessage(Debug, "%s Translate server, %s -> %s\n", wordbuf, chinese.c_str());
}
void Transform(int sockfd, InetAddr addr)
{
    lg.LogMessage(Debug, "%s select %s is success, fd: %d \n", addr.PrintDebug().c_str(), "Transform", sockfd);
    char wordbuf[64];  
    ssize_t n = read(sockfd, wordbuf, sizeof(wordbuf) - 1);
    if(n > 0) wordbuf[n] = 0;

    string message = wordbuf;

    transform(message.begin(), message.end(), message.begin(), [](unsigned char c){
        return toupper(c);
    });

    write(sockfd, message.c_str(), message.size());
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        return Usage_Err;
    }
    uint16_t port = stoi(argv[1]);
    // Daemon(false, false);
    // lg.Enable(ClassFile);

    unique_ptr<Tcp_Server> tsvr(new Tcp_Server(port));

    tsvr->RigisterFunc("ping", Ping);
    tsvr->RigisterFunc("translate", Translate);
    tsvr->RigisterFunc("transform", Transform);

    tsvr->Init();
    tsvr->Start();

    return 0;
}